#include "controladorjogo.h"
#include <QDebug>
#include "exception.h"

ControladorJogo::ControladorJogo():
    pontoXFoiSobrepintadoPorHeroi(false),
    pontoXFoiSobrepintadoPorCaixa(false),
    contadorPontoXComCaixa(0)
{
}

ControladorJogo::ControladorJogo(QString &path):
    _painter(new QPainter()),
    _faseIO(new FaseIO(path)),
    pontoXFoiSobrepintadoPorHeroi(false),
    pontoXFoiSobrepintadoPorCaixa(false),
    contadorPontoXComCaixa(0)
{
    this->_faseIO->carregar(this->_fase);

    this->_pixmapImgJogo = QPixmap::fromImage(this->_fase.imagemFase());
    this->_painter->begin(&this->_pixmapImgJogo);
}

ControladorJogo::~ControladorJogo()
{
    this->_painter->end();
    delete this->_painter;
    delete this->_faseIO;
}

QPixmap ControladorJogo::pixmapImgJogo()const
{
    return this->_pixmapImgJogo;
}

void ControladorJogo::movimentarHeroi(QPoint &deslocamento)
{
    QPoint pontoDestino = this->_fase.pontoPartida() + deslocamento;

    if((pontoDestino.x() > (editacao::WIDTH_FASE - editacao::WIDTH_ELEMENTOS) || pontoDestino.x() < 0) || (pontoDestino.y() > (editacao::HEIGHT_FASE - editacao::HEIGHT_ELEMENTOS) || pontoDestino.y() < 0))
    {
        throw Exception("Movimento nao permitido. Voce ficaria fora dos limites da fase");
    }

    editacao::Elementos elemento;

    if(this->_fase.contemElemento(pontoDestino))
    {
        elemento = this->_fase.elemento(pontoDestino);
        switch(elemento)
        {
            case editacao::PONTOX:
                this->_elementoDeFase = ElementoDeFase(editacao::CHAO);
                this->_painter->drawImage(this->_fase.pontoPartida(), this->_elementoDeFase.imagemElementoDeFase());

                this->_fase.setPontoPartida(pontoDestino);
                this->_elementoDeFase = ElementoDeFase(editacao::HEROI);
                this->_painter->drawImage(pontoDestino, this->_elementoDeFase.imagemElementoDeFase());
                this->pontoXFoiSobrepintadoPorHeroi = true;

                break;
            case editacao::CAIXA:
            {
                QPoint pontoDestinoCaixa = pontoDestino + deslocamento;

                if((pontoDestinoCaixa.x() > (editacao::WIDTH_FASE - editacao::WIDTH_ELEMENTOS) || pontoDestinoCaixa.x() < 0) || (pontoDestinoCaixa.y() > (editacao::HEIGHT_FASE - editacao::HEIGHT_ELEMENTOS) || pontoDestinoCaixa.y() < 0))
                {
                    throw Exception("Movimento nao permitido. A caixa ficaria fora dos limites da fase");
                }

                this->movimentarCaixa(pontoDestino, deslocamento);
            }
                break;
            default:
                break;
        }
    }
    else
    {
        if(this->pontoXFoiSobrepintadoPorHeroi)
        {
            this->_elementoDeFase = ElementoDeFase(editacao::PONTOX);
            this->pontoXFoiSobrepintadoPorHeroi = false;
        }
        else this->_elementoDeFase = ElementoDeFase(editacao::CHAO);
        this->_painter->drawImage(this->_fase.pontoPartida(), this->_elementoDeFase.imagemElementoDeFase());

        this->_fase.setPontoPartida(pontoDestino);
        this->_elementoDeFase = ElementoDeFase(editacao::HEROI);
        this->_painter->drawImage(pontoDestino, this->_elementoDeFase.imagemElementoDeFase());

    }


}

void ControladorJogo::movimentarCaixa(QPoint &pontoPartida, QPoint &deslocamento)
{
    editacao::Elementos elemento;
    QPoint pontoDestino = pontoPartida + deslocamento;

    if(this->_fase.contemElemento(pontoDestino))
    {
        elemento = this->_fase.elemento(pontoDestino);
        switch(elemento)
        {
            case editacao::PONTOX:
                this->pontoXFoiSobrepintadoPorCaixa = true;
                this->contadorPontoXComCaixa++;

                this->_fase.removeElemento(pontoPartida);
                this->_fase.insereCaixaEmPontoX(pontoDestino);

                this->movimentarHeroi(deslocamento);

                this->_elementoDeFase = ElementoDeFase(editacao::CAIXA);
                this->_painter->drawImage(pontoDestino, this->_elementoDeFase.imagemElementoDeFase());




                if(this->contadorPontoXComCaixa == this->_fase.totalPontoX())
                {
                    //acabou a fase
                }

                break;
            default:
                break;
        }
    }
    else
    {
        this->_elementoDeFase = ElementoDeFase(editacao::CHAO);
        this->_painter->drawImage(this->_fase.pontoPartida(), this->_elementoDeFase.imagemElementoDeFase());

        this->_elementoDeFase = ElementoDeFase(editacao::HEROI);
        this->_fase.setPontoPartida(pontoPartida);
        this->_painter->drawImage(pontoPartida, this->_elementoDeFase.imagemElementoDeFase());
        this->_fase.removeElemento(pontoPartida);

        this->_elementoDeFase = ElementoDeFase(editacao::CAIXA);
        this->_painter->drawImage(pontoDestino, this->_elementoDeFase.imagemElementoDeFase());
        this->_fase.insereElemento(pontoDestino, this->_elementoDeFase.elemento());


    }
}
